package com.Liyunhan.design;

import org.jfree.chart.ChartPanel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;

/**
 * @Description: 图形用户界面 (目前仅实现了几何分布, 具体内容参见normalization接口描述)
 * ------------->使用说明<---------------
 * 1. 首先输入参数, 以几何分布为例, 在第一个框内输入参数n(试验次数), 第二个框内输入成功概率p, 点击confirm确定
 * 2. 点击左上角切换到分布选择, 选择要模拟的分布
 * @Author: Liyunhan
 * @Date: 2021/12/18 17:23
 */
public class GUI implements normalization {
    private ItemEvent itemEvent;
    private String[] distributions = {"BetaDistribution", "BinomialDistribution", "CauchyDistribution", "Chi-squaredDistribution",
            "ConstantRealDistribution", "EnumeratedDistribution", "ExponentialDistribution", "F-distribution", "GammaDistribution",
            "GeometricDistribution", "GumbelDistribution", "HypergeometricDistribution", "KolmogorovSmirnovDistribution", "LaplaceDistribution",
            "LevyDistribution", "LogisticDistribution", "MultivariateNormalDistribution", "NakagamiDistribution", "NormalDistribution",
            "ParetoDistribution", "PascalDistribution", "PoissonDistribution", "TDistribution", "TriangularDistribution", "UniformIntegerDistribution",
            "UniformRealDistribution", "WeibullDistribution", "ZipfDistribution"};

    private JTabbedPane buildJTabbedPane(JPanel buttonAndText, JPanel dbPanel, ArrayList hyperparams, ArrayList simuResults, ArrayList calResults) {
        // 选项卡面板
        JTabbedPane tabbedPane = new JTabbedPane();
        // 通过BorderFactory来设置边框的特性
        tabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        tabbedPane.add("参数设置", buttonAndText);
        tabbedPane.add("概率分布", dbPanel);


        dbPanel.add(this.buildJLabel("请选择分布类型", 10, 20, 150, 25));

        dbPanel.add(this.buildJComboBox("distributions", "distributions", distributions, 0, 100, 20, 165, 25, hyperparams, simuResults, calResults));
        return tabbedPane;
    }

    private void buildFrame(JComponent component) {
        // 窗体容器
        JFrame frame = new JFrame("概率分布工具箱");
        frame.add(component);
        //  JFrame.EXIT_ON_CLOSE  退出
        //  JFrame.HIDE_ON_CLOSE  最小化隐藏
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置布局
        frame.getContentPane().setLayout(new BorderLayout());
        frame.getContentPane().add(BorderLayout.CENTER, component);
        // 设置窗口最小尺寸
        frame.setMinimumSize(new Dimension(1060, 560));
        // 调整此窗口的大小，以适合其子组件的首选大小和布局
        frame.pack();
        // 设置窗口相对于指定组件的位置
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        // 设置窗口尺寸是否固定不变
        frame.setResizable(true);
    }

    private JComboBox buildJComboBox(Object selectedItem, String name, String[] elements, int selectedIndex, int x, int y, int width, int height, ArrayList hyperparams, ArrayList simuResults, ArrayList calResults) {
        DefaultComboBoxModel codeTypeModel = new DefaultComboBoxModel();
        // elements 下拉框中的选项
        for (String element : elements) {
            codeTypeModel.addElement(element);
        }
        JComboBox codeTypeBox = new JComboBox(codeTypeModel);
        codeTypeBox.setName(name);
        // 默认选中的下拉框选项
        codeTypeBox.setSelectedItem(selectedItem);
//        codeTypeBox.setSelectedItem(selectedIndex);
        codeTypeBox.setBounds(x, y, width, height);
        // 添加下拉框事件监听器
        codeTypeBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    // 选择的下拉框选项
                    System.out.println(e.getItem());
                    // 拿到选中的分布类型, 开始执行模拟
                    startSimu(hyperparams, simuResults, calResults, (String) e.getItem());
                    MyJfreechart myJfreechart = new MyJfreechart(simuResults, calResults);
                    JPanel jPanel = new ChartPanel(myJfreechart.getChartObj());
                    JFrame frame = new JFrame((String) e.getItem());
                    frame.add(jPanel);
                    frame.setBounds(0, 0, 800, 600);
                    frame.setVisible(true);
                }
            }
        });
        return codeTypeBox;
    }

    private JLabel buildJLabel(String name, int x, int y, int width, int height) {
        JLabel label = new JLabel(name);
        label.setBounds(x, y, width, height);
        return label;
    }

    public static void main(String[] args) {
        ArrayList hyperparams = new ArrayList();
        ArrayList simuResults = new ArrayList();
        ArrayList calResults = new ArrayList();
//        hyperparams.add(0, new Integer(1000));
//        hyperparams.add(1, new Double(0.01));


        GUI gui = new GUI();
        // 面板组件
        // 面板输入组件
        // 数据数量n
        JPanel buttonAndText = new JPanel();
        Button n = new Button("confirm");
        JTextField num = new JTextField(10);

        buttonAndText.add(n);
        buttonAndText.add(num);
        // 概率p
        JTextField probability = new JTextField(10);
        buttonAndText.add(probability);

        // 添加事件监听(输入完确认输入数据)
        n.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String text1 = num.getText();
                String text2 = probability.getText();
                hyperparams.add(0, Integer.parseInt(text1));
                hyperparams.add(1, Double.parseDouble(text2));
            }

        });

        JPanel dbPanel = new JPanel();
        JTabbedPane tabbedPane = gui.buildJTabbedPane(buttonAndText, dbPanel, hyperparams, simuResults, calResults);
        gui.buildFrame(tabbedPane);
    }

    /**
     * 目前仅实现了几何分布
     * 由于对象地址传值, 对应类的实例就直接改变了对应的list, 也就拿到了数据
     *
     * @param hyperparams
     * @param simuResults
     * @param calResults
     * @param distributionName
     */
    @Override
    public void startSimu(ArrayList hyperparams, ArrayList simuResults, ArrayList calResults, String distributionName) {
        //实例化指定分布类对象
        switch (distributionName) {
            case "GeometricDistribution":
                new GeometricDistribution(hyperparams, simuResults, calResults);
                break;
            case "BinomialDistribution":
//                new BinomialDistribution(hyperparams, simuResults, calResults);
                break;
            case "BetaDistribution":
//                new BetaDistribution(hyperparams, simuResults, calResults);
                break;
            case "EnumeratedDistribution":
//                new EnumeratedDistribution(hyperparams, simuResults, calResults);
                break;
            case "CauchyDistribution":
//                new CauchyDistribution(hyperparams, simuResults, calResults);
                break;
            case "ConstantRealDistribution":
//                new ConstantRealDistribution(hyperparams, simuResults, calResults);
                break;
            case "ParetoDistribution":
//                new ParetoDistribution(hyperparams, simuResults, calResults);
                break;
            case "WeibullDistribution":
//                new WeibullDistribution(hyperparams, simuResults, calResults);
                break;
            default:
                break;
        }

    }
}


